import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.HashMap;
/**
 * Class to handle input from the keyboard and mouse.  Does things in a nice manner
 * for games and the such.  Allows multiple keys to be pressed at the same time and
 * ability to poll the keys.
 * 
 * @author ggere
 *
 */

public class InputManager {
	
	// array of our key states
	private boolean keyState[];

	// the collection of our inputCollections
	private HashMap<String, InputCollection> inputCollections;
	
	// these are the events that can be mapped and polled by the game components
	public static int EVENT_UP       = 1;
	public static int EVENT_DOWN     = 2;
	public static int EVENT_LEFT     = 3;
	public static int EVENT_RIGHT    = 4;
	public static int EVENT_FIRE     = 5;
	public static int EVENT_ALTFIRE  = 6;
	public static int EVENT_QUIT     = 999;

	
	/**
	 * Constructor, initializes the array of key states to be off.
	 */
	public InputManager () {
		inputCollections = new HashMap<String, InputCollection>();
		
        // set all keys to off cleared
		keyState = new boolean[256];
		for (int i = 0; i < 256; i++) {
			keyState[i] = false;
		}	
	}
	
	/**
	 * Maps a key to an event in the inputCollection whose name is specified by
	 * the name parameter.
	 * TODO: Allow multiple handlers for the same key.
	 * @param name the name of the inputCollection to use
	 * @param event the game event code
	 * @param key the key code
	 */
	public void map(String name, int event, int key) {
		// check if the inputCollection already exists
		if (inputCollections.containsKey(name)) {
			// it does, so lets add that map.
			InputCollection i = (InputCollection)inputCollections.get(name);
			i.map(event, key);
		}
		else {
			// it doesn't, so create new inputCollection, map the key to the event
			// and add it to the collection of inputCollections
			InputCollection i = new InputCollection(name);
			i.map(event, key);
			inputCollections.put(name, i);
		}
		
		System.out.println("Mapped event " + getEventText(event) + " in " + name + " to " + KeyEvent.getKeyText(key) );
	}
	
	/**
	 * Clears the mapping for the requested game event.
	 * @param event the event in question
	 */
	public void clear(String name, int event) {
		if (inputCollections.containsKey(name)) {
			InputCollection i = (InputCollection)inputCollections.get(name);
			i.clear(event);
		}
	}

	/**
	 * Polls the state of the input (just keys at the moment), based on the name
	 * which identifies who is calling. 
	 * @param name the name of the player/object that is calling this function
	 * @param event the event or input whose state is being queried.
	 * @return true or false depending on if the input is on or off.
	 */
    public boolean poll(String name, int event) {
		if (inputCollections.containsKey(name)) {
			InputCollection i = (InputCollection)inputCollections.get(name);
			int key = i.get(event);
			
			//System.out.println("Polled " + event + " from " + name + " =  event " + event + ", which is " + keyState[key]);
			return keyState[key];
		}
    	return false;
    }
    
    /**
     * Returns a string describing the event that the event id refers to.
     * @param event the event id
     * @return a string
     */
    public String getEventText(int event) {
    	String output = "UNKNOWN";
    	switch ( event ) {
    		case 1: output = "UP"; break;
    		case 2: output = "DOWN"; break;
    		case 3: output = "LEFT"; break;
    		case 4: output = "RIGHT"; break;
    		case 5: output = "FIRE"; break;
    		case 6: output = "ALT_FIRE"; break;
    		case 999: output = "QUIT"; break;
    	}
    	return output;
    }
    
	
	// Mouse handlers
	public void mousePressed (MouseEvent e) {}
    public void mouseDragged (MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseMoved   (MouseEvent e) {}
    public void mouseEntered (MouseEvent e) {}
    public void mouseExited  (MouseEvent e) {}
    public void mouseClicked (MouseEvent e) {}

    public void keyPressed(KeyEvent e) {
    	// turn on the key
    	int key = e.getKeyCode();
    	keyState[key] = true;
    	
    	//System.out.println("Key " + e.getKeyChar() + " [" + key + "] is on.");
    }

    public void keyReleased(KeyEvent e) {
    	// turn off the key
    	int key = e.getKeyCode();
    	keyState[key] = false;
    	//System.out.println("Key " + e.getKeyChar() + " [" + key + "] is off.");    	
    }  
}
